﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace SemestralniPraceY35VAN
{
    class Checkin
    {
        /// <summary>
        /// Properties of the checkin.
        /// </summary>
        private Hashtable properties;

        /// <summary>
        /// 
        /// </summary>
        public string ID { get { if (properties.ContainsKey("id")) return (string)properties["id"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public DateTime Created { get { if (properties.ContainsKey("created")) { DateTime created = new DateTime(); created = DateTime.Parse((string)properties["created"]); return created; } else return DateTime.Today; } }

        /// <summary>
        /// 
        /// </summary>
        public string Before
        {
            get
            {
                if (properties.ContainsKey("created"))
                {
                    TimeSpan before = DateTime.Now - this.Created;

                    if (before.Days == 0)
                    {
                        if (before.Hours == 0)
                        {
                            if (before.Minutes < 3)
                            {
                                return "just now";
                            }
                            else
                            {
                                return Convert.ToString(before.Minutes) + " minutes ago";
                            }
                        }
                        else if (before.Hours == 1)
                        {
                            return Convert.ToString(before.Hours) + " hour ago";
                        }
                        else
                        {
                            return Convert.ToString(before.Hours) + " hours ago";
                        }
                    }
                    else if (before.Days == 1)
                    {
                        return Convert.ToString(before.Days) + " day ago";
                    }
                    else
                    {
                        return Convert.ToString(before.Days) + " days ago";
                    }
                }
                else
                {
                    return "";
                }
            }
        }

        public string Age
        {
            get
            {
                if (this.Created.Date.Equals(DateTime.Today.Date))
                {
                    return "Today";
                }
                else if (this.Created.Date.Equals(DateTime.Today.AddDays(-1).Date))
                {
                    return "Yesterday";
                }
                else
                {
                    int diff = DateTime.Today.DayOfWeek - DayOfWeek.Monday;

                    if (diff < 0)
                    {
                        diff += 7;
                    }

                    DateTime monday = DateTime.Today.AddDays(-1 * diff).Date;
                    
                    if (this.Created.Date.CompareTo(monday) > -1)
                    {
                        return "This Week";
                    }
                    else
                    {
                        return "Older";
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Venue Venue { get { if (properties.ContainsKey("venue")) return (Venue)properties["venue"]; else return null; } }

        /// <summary>
        /// Distance of the venue.
        /// </summary>
        public int Distance { get { if (properties.ContainsKey("distance")) return int.Parse((string)properties["distance"]); else return -1; } }

        /// <summary>
        /// 
        /// </summary>
        public User User { get { if (properties.ContainsKey("user")) return (User)properties["user"]; else return null; } }

        /// <summary>
        /// 
        /// </summary>
        public string Display { get { if (properties.ContainsKey("display")) return (string)properties["display"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public string Message { get { if (properties.ContainsKey("message")) return (string)properties["message"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public string Shout { get { if (properties.ContainsKey("shout")) return (string)properties["shout"]; else return ""; } }

        /// <summary>
        /// 
        /// </summary>
        public List<Badge> Badges { get { if (properties.ContainsKey("badges")) return (List<Badge>)properties["badges"]; else return null; } }

        /// <summary>
        /// 
        /// </summary>
        public List<Score> Scoring { get { if (properties.ContainsKey("scoring")) return (List<Score>)properties["scoring"]; else return null; } }

        /// <summary>
        /// 
        /// </summary>
        public List<Special> Specials { get { if (properties.ContainsKey("specials")) return (List<Special>)properties["specials"]; else return null; } }

        /// <summary>
        /// Constructs an object representing a check-in.
        /// </summary>
        /// <param name="venue">XML node with information about the check-in</param>
        public Checkin(XmlNode checkin)
        {
            properties = new Hashtable();

            if (checkin.Name == "checkin")
            {
                for (int i = 0; i < checkin.ChildNodes.Count; i++)
                {
                    switch (checkin.ChildNodes[i].Name)
                    {
                        case "venue":
                            properties.Add(checkin.ChildNodes[i].Name, new Venue(checkin.ChildNodes[i]));
                            break;
                        case "user":
                            properties.Add(checkin.ChildNodes[i].Name, new User(checkin.ChildNodes[i]));
                            break;
                        case "mayor":
                            properties.Add(checkin.ChildNodes[i].Name, new Mayor(checkin.ChildNodes[i]));
                            break;
                        case "badges":
                            List<Badge> badges = new List<Badge>();

                            foreach (XmlNode badge in checkin.ChildNodes[i].ChildNodes)
                            {
                                badges.Add(new Badge(badge));
                            }

                            properties.Add(checkin.ChildNodes[i].Name, badges);
                            break;
                        case "scoring":
                            List<Score> scoring = new List<Score>();

                            foreach (XmlNode score in checkin.ChildNodes[i].ChildNodes)
                            {
                                scoring.Add(new Score(score));
                            }

                            properties.Add(checkin.ChildNodes[i].Name, scoring);
                            break;
                        case "specials":
                            List<Special> specials = new List<Special>();

                            foreach (XmlNode special in checkin.ChildNodes[i].ChildNodes)
                            {
                                specials.Add(new Special(special));
                            }

                            properties.Add(checkin.ChildNodes[i].Name, specials);
                            break;
                        default:
                            properties.Add(checkin.ChildNodes[i].Name, checkin.ChildNodes[i].InnerText);
                            break;
                    }
                }
            }
            else
            {
                throw new IOException("Not Check-in!");
            }
        }
    }
}
